﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System.ComponentModel;
using ImageAppDataModels;
using BrainTechLLC.FilterExtensions;
using BrainTechLLC.ImageOperators;
using BrainTechLLC.ImageOperatorsNonAForgeDependent;
using BrainTechLLC;
using BrainTechLLC.WPF;
using System;
using System.Reflection;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Windows;
using BrainTechLLC.WebCamLib3;
using System.Drawing;
using System.Windows.Media;

namespace WebCam
{
    public class MotionProcessingViewModel : BaseNotifyPropertyChanged, IPostProcessor
    {
        public event EventHandler RaiseMovementAlarm;
        protected CameraHandler _cameraHandler;
        protected MotionProcessing _motionProcessor;
        protected bool _movementAlarmOn;
        protected DateTime _lastMotionDetected;

        public string Name { get { return "MotionProcessing"; } }

        public DateTime LastMotionDetected
        {
            get { return _lastMotionDetected; }
            set
            {
                if (_lastMotionDetected != value)
                {
                    _lastMotionDetected = value;
                    OnPropertyChanged("LastMotionDetected");
                }
            }
        }

        public bool MovementAlarmOn
        {
            get { return _movementAlarmOn; }
            set
            {
                if (_movementAlarmOn != value)
                {
                    _movementAlarmOn = value;
                    OnPropertyChanged("MovementAlarmOn");
                }
            }
        }

        public bool HighlightMotion
        {
            get { return _motionProcessor.HighlightMotion; }
            set
            {
                if (_motionProcessor.HighlightMotion != value)
                {
                    _motionProcessor.HighlightMotion = value;                    
                }
            }
        }

        public bool Enabled
        {
            get { return !_motionProcessor.Disabled; }
            set
            {
                if (_motionProcessor.Disabled != !value)
                {
                    _motionProcessor.Disabled = !value;
                    OnPropertyChanged("Enabled");
                }
            }
        }


        public bool Disabled
        {
            get { return _motionProcessor.Disabled; }
            set
            {
                if (_motionProcessor.Disabled != value)
                {
                    _motionProcessor.Disabled = value;
                    OnPropertyChanged("Enabled");
                }
            }
        }

        public int MotionSensitivity
        {
            get { return _motionProcessor.MotionSensitivity; }
            set
            {
                if (_motionProcessor.MotionSensitivity != value)
                {
                    _motionProcessor.MotionSensitivity = value;
                    OnPropertyChanged("MotionSensitivity");
                }
            }
        }
        
        public int MotionMinimumBlockSensitivity
        {
            get { return _motionProcessor.MotionMinimumBlockSensitivity; }
            set
            {
                if (_motionProcessor.MotionMinimumBlockSensitivity != value)
                {
                    _motionProcessor.MotionMinimumBlockSensitivity = value;
                    OnPropertyChanged("MotionMinimumBlockSensitivity");
                }
            }
        }
        
        public bool DetectMotion
        {
            get { return _motionProcessor.DetectMotion; }
            set
            {
                if (_motionProcessor.DetectMotion != value)
                {
                    _motionProcessor.DetectMotion = value;
                    OnPropertyChanged("DetectMotion");
                }
            }
        }

        public MotionProcessingViewModel(CameraHandler cameraHandler, MotionProcessing motionProcessing)
        {
            _cameraHandler = cameraHandler;
            _motionProcessor = motionProcessing;
            _motionProcessor.PropertyChanged += new PropertyChangedEventHandler(_motionProcessor_PropertyChanged);
            _motionProcessor.MotionDetected += new EventHandler<ObjectEventArgs<FrameInfo>>(_motionProcessor_MotionDetected);
            _cameraHandler.GatherPostProcessors += new EventHandler<ObjectEventArgs<List<IPostProcessor>>>(_cameraHandler_GatherPostProcessors);
        }

        public bool ProcessBitmap(FrameInfo frameInfo)
        {
            return _motionProcessor.ProcessBitmap(frameInfo);
        }

        void _motionProcessor_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnPropertyChanged(e.PropertyName);
        }

        void _motionProcessor_MotionDetected(object sender, ObjectEventArgs<FrameInfo> e)
        {
            Application.Current.Dispatcher.RunOnDispatcher(new VoidDelegate(() =>
            {
                LastMotionDetected = DateTime.Now;

                if (MovementAlarmOn)
                {
                    if (RaiseMovementAlarm != null)
                    {
                        RaiseMovementAlarm(this, EventArgs.Empty);
                    }
                }
            }), 
            System.Windows.Threading.DispatcherPriority.Normal);
        }

        void _cameraHandler_GatherPostProcessors(object sender, ObjectEventArgs<List<IPostProcessor>> e)
        {
            e.obj.Add(_motionProcessor);
        }
    }
}